﻿using Digitalmes.Attributes;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Reflection;
using System.Threading.Tasks;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Extensions;
using WalkingTec.Mvvm.Mvc;

namespace Digitalmes.ActionFilters
{
    /// <summary>
    /// 工作单元筛选器
    /// </summary>
    public sealed class UnitOfWorkFilter : IAsyncActionFilter, IOrderedFilter
    {
        public int Order => 100;

        private readonly ILogger _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="Wtm"></param>

        public UnitOfWorkFilter(ILogger<UnitOfWorkFilter> logger)
        {
            _logger = logger;
        }

        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            //这里获取Wtm 控制器接口
            //var controller = context.Controller as IBaseController;

            // 获取动作方法描述器
            var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
            var attribute = actionDescriptor?.MethodInfo.GetCustomAttribute<UnitOfWorkAttribute>(false);
            if (attribute == null)
            {
                _ = await next();
                return;
            }

            var wtm = context.HttpContext.RequestServices.GetService<WTMContext>();
            if (wtm is null)
            {
                return;
            }

            // 开启事务
            using (var tran=wtm.DC.BeginTransaction())
            {
              
                // 调用方法
                var resultContext = await next();

                if (resultContext.Exception == null)
                {
                    // 没有异常，尝试提交
                    try
                    {
                      await tran.CommitAsync();
                    }
                    catch (Exception ex)
                    {
                        await tran.RollbackAsync();

                        _logger.LogError(ex, "事务提交失败，Controller: {ControllerName}, Action: {ActionName}", actionDescriptor!.ControllerName, actionDescriptor!.ActionName);
                    }
                    
                }
                
            }
           
        }
    }

}
